/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package utfpr.cp.crawler;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Adriano_2
 */
public class CrawlerStats {
    private int thread;
    private long totalProcessedURL;
    private long totalVisitedPages;
    private long totalSavedPages;
    private long totalDatabaseErrors;
    private long totalErrors;
    private long lastTime;
    private double mbytes; 

    private String domain = "";
    public CrawlerStats(String domain) {
        this(0);
        this.domain = domain;
    }
    
    public CrawlerStats(int thread) {
        this.thread = thread;
        totalProcessedURL = 0;
        totalVisitedPages = 0;
        totalSavedPages = 0;
        totalDatabaseErrors = 0;
        totalErrors = 0;
        lastTime = 0;
    }
    
    /**
     * @return the totalProcessedURL
     */
    public long getTotalProcessedURL() {
        return totalProcessedURL;
    }

    /**
     * @param totalProcessedURL the totalProcessedURL to set
     */
    public void setTotalProcessedURL(long totalProcessedURL) {
        this.totalProcessedURL = totalProcessedURL;
    }

    /**
     * @return the totalVisitedPages
     */
    public long getTotalVisitedPages() {
        return totalVisitedPages;
    }

    /**
     * @param totalVisitedPages the totalVisitedPages to set
     */
    public void setTotalVisitedPages(long totalVisitedPages) {
        this.totalVisitedPages = totalVisitedPages;
    }

    /**
     * @return the totalErrors
     */
    public long getTotalErrors() {
        return totalErrors;
    }

    /**
     * @param totalErrors the totalErrors to set
     */
    public void setTotalErrors(long totalErrors) {
        this.totalErrors = totalErrors;
    }

    /**
     * @return the thread
     */
    public int getThread() {
        return thread;
    }

    /**
     * @return the totalSavedPages
     */
    public long getTotalSavedPages() {
        return totalSavedPages;
    }

    /**
     * @param totalSavedPages the totalSavedPages to set
     */
    public void setTotalSavedPages(long totalSavedPages) {
        this.totalSavedPages = totalSavedPages;
    }

    /**
     * @return the totalDatabaseErrors
     */
    public long getTotalDatabaseErrors() {
        return totalDatabaseErrors;
    }

    /**
     * @param totalDatabaseErrors the totalDatabaseErrors to set
     */
    public void setTotalDatabaseErrors(long totalDatabaseErrors) {
        this.totalDatabaseErrors = totalDatabaseErrors;
    }
    
    void addTotalProcessedURL() {
        totalProcessedURL++;
    }

    void addTotalVisitedPages() {
        totalVisitedPages++;
    }

    void addTotalSavedPages() {
        totalSavedPages++;
    }

    void addErrorPages() {
        totalErrors++;
    }

    void addDatabaseErrors() {
        totalDatabaseErrors++;
    }
    
    public long getTotalAllErrors() {
        return totalDatabaseErrors + totalErrors;
    }
    
    @Override
    public String toString() {
        String time = "No time yet";
        if (lastTime > 0) { 
            if (lastTime < 60000) {
                time = (lastTime / 1000) + " seg";
            }
            else {
                time =   (lastTime / 60000) + " min.";
            }
        }
        String tid;
        if (getDomain().isEmpty()) {
            tid = String.valueOf(thread);
        }
        else {
            tid = getDomain();
        }
        return "[" + tid + "] " + time + " \n" +
            "Processed URL: " + totalProcessedURL + "\n" +
            "Visited Pages: " + totalVisitedPages + "\n" +
            "  Saved Pages: " + totalSavedPages + "\n" + 
            "    DB errors: " + totalDatabaseErrors + "\n" + 
            "  HTTP errors: " + totalErrors + "\n";
    }
    
    private static List<CrawlerStats> threads;
    public static void register(CrawlerStats item) {
        if (threads == null) {
            threads = new ArrayList<>();
        }
        if (!threads.contains(item)) {
            threads.add(item);
        }
    }
    
    public static List<CrawlerStats> getList() {
        if (threads == null) {
            threads = new ArrayList<>();
        }
        return threads;
    }

    public static void resetList() {
        threads = new ArrayList<>();
    }

    /**
     * @return the lastTime
     */
    @Deprecated
    public long getLastTime() {
        return lastTime;
    }

    /**
     * @param lastTime the lastTime to set
     */
    @Deprecated
    public void setLastTime(long lastTime) {
        this.lastTime = lastTime;
    }

    /**
     * @return the domain
     */
    public String getDomain() {
        return domain;
    }

    void merge(CrawlerStats stats) {
        setTotalDatabaseErrors(getTotalDatabaseErrors() + stats.getTotalDatabaseErrors());
        setTotalErrors(getTotalErrors() + stats.getTotalErrors());
        setTotalProcessedURL(getTotalProcessedURL() + stats.getTotalProcessedURL());
        setTotalVisitedPages(getTotalVisitedPages()+ stats.getTotalVisitedPages());
        setTotalSavedPages(getTotalSavedPages()+ stats.getTotalSavedPages());
        setTotalMbytes(getTotalMbytes() + stats.getTotalMbytes());
    }

    /**
     * @return the mbytes
     */
    public double getTotalMbytes() {
        return mbytes;
    }

    /**
     * @param mbytes the mbytes to set
     */
    public void addTotalMbytes(double mbytes) {
        this.mbytes += mbytes;
    }
    
    public void addTotalKbytes(double kbytes) {
        addTotalMbytes(kbytes/1024.0);
    }
    
    public void addTotalBytes(long bytes) {
        addTotalKbytes(bytes/1024.0);
    }

    /**
     * @param mbytes the mbytes to set
     */
    public void setTotalMbytes(double mbytes) {
        this.mbytes = mbytes;
    }
}
